Return to Main Page

\(\color{darkblue}{\textbf{sf}}\)


Used for processing spatial data and basic visualization

library(tidyverse)
library(sf)

\(\color{dodgerblue}{\textbf{Importing}}\)


\(\color{skyblue}{\textrm{- Reading in Data}}\)

spatial <- read_sf("pathway/to/shapefile.shp")
spatial <- read_csv("pathway/to/spatial.csv") %>% 
  st_as_sf()

\(\color{dodgerblue}{\textbf{Removing Geometry}}\)

non_spatial <- spatial %>% 
  st_set_geometry(NULL)

\(\color{dodgerblue}{\textbf{Geocoding}}\)

boro_halls <- tibble(hall = c("New York City Hall", "Manhattan Municipal Building", "Bronx County Courthouse",
                              "Brooklyn Borough Hall", "Queens Borough Hall", "Staten Island Borough Hall"),
                     street = c("New York City Hall, New York, NY 10007", "31 Chambers St, New York, NY 10007",
                                "851 Grand Concourse, Bronx, NY 10451", "209 Joralemon St, Brooklyn, NY 11201",
                                "120-55 Queens Blvd, Queens, NY 11424", "10 Richmond Terrace, Staten Island, NY 10301"))

boro_halls
hall street
New York City Hall New York City Hall, New York, NY 10007
Manhattan Municipal Building 31 Chambers St, New York, NY 10007
Bronx County Courthouse 851 Grand Concourse, Bronx, NY 10451
Brooklyn Borough Hall 209 Joralemon St, Brooklyn, NY 11201
Queens Borough Hall 120-55 Queens Blvd, Queens, NY 11424
Staten Island Borough Hall 10 Richmond Terrace, Staten Island, NY 10301


\(\color{skyblue}{\textrm{- Cleaning Messy Addresses}}\)

#remotes::install_github("slu-openGIS/postmastr")
library(postmastr)

boro_halls <- boro_halls %>% 
  pm_identify(var = "street")

boro_halls_unique <- boro_halls %>% 
  pm_prep(var = "street", type = "street")

#Check ZIP Code
boro_halls_unique %>% pm_postal_all()
[1] TRUE
boro_halls_unique <- boro_halls_unique %>% 
  pm_postal_parse()

#Check State
nyDict <- pm_dictionary(locale = "us", type = "state", filter = "NY", case = c("title", "upper"))

boro_halls_unique %>% pm_state_all(dictionary = nyDict)
[1] TRUE
boro_halls_unique <- boro_halls_unique %>% 
  pm_state_parse()

#Check City
defaultDict <- pm_dictionary(locale = "us", type = "city", filter = "NY")
specificDict <- pm_append(type = "city",
                          input = c("New York", "New York City", "NYC",     "Bronx", "The Bronx", "Brooklyn", "Queens", "Jamaica", "Staten Island"),
                          output = c(NA       , "New York"     , "New York", NA    , "Bronx"    , NA        , NA      , "Queens" , NA))

boro_halls_unique %>% pm_city_all(dictionary = specificDict)
[1] TRUE
boro_halls_unique <- boro_halls_unique %>% 
  pm_city_parse(dictionary = specificDict)

#Check Number
boro_halls_unique %>% pm_house_all()
[1] FALSE
#Check Missing
boro_halls_unique %>% pm_house_none()
pm.uid pm.address pm.city pm.state pm.zip
1 New York City Hall New York NY 10007
boro_halls_unique <- boro_halls_unique %>% 
  pm_house_parse()

#Check Street Direction (e.g. East Broadway)
boro_halls_unique %>% pm_streetDir_all()
[1] FALSE
#Check Missing
boro_halls_unique %>% pm_streetDir_none()
pm.uid pm.address pm.house pm.city pm.state pm.zip
1 New York City Hall NA New York NY 10007
2 Chambers St 31 New York NY 10007
3 Grand Concourse 851 Bronx NY 10451
4 Joralemon St 209 Brooklyn NY 11201
5 Queens Blvd 120-55 Queens NY 11424
6 Richmond Terrace 10 Staten Island NY 10301
#Check Street Suffix 
boro_halls_unique %>% pm_streetSuf_all()
[1] FALSE
#Check Missing
boro_halls_unique %>% pm_streetSuf_none()
pm.uid pm.address pm.house pm.city pm.state pm.zip
1 New York City Hall NA New York NY 10007
3 Grand Concourse 851 Bronx NY 10451
boro_halls_unique <- boro_halls_unique %>% 
  pm_streetSuf_parse()

#Street is assumed 
boro_halls_unique <- boro_halls_unique %>% 
  pm_street_parse()

#Reassemble
boro_halls_parsed <- pm_replace(boro_halls_unique, source = boro_halls) %>% 
  pm_rebuild(output = "full", keep_parsed = "no")

boro_halls_parsed
hall street pm.address
New York City Hall New York City Hall, New York, NY 10007 New York City Hall New York NY 10007
Manhattan Municipal Building 31 Chambers St, New York, NY 10007 31 Chambers St New York NY 10007
Bronx County Courthouse 851 Grand Concourse, Bronx, NY 10451 851 Grand Concourse Bronx NY 10451
Brooklyn Borough Hall 209 Joralemon St, Brooklyn, NY 11201 209 Joralemon St Brooklyn NY 11201
Queens Borough Hall 120-55 Queens Blvd, Queens, NY 11424 120-55 Queens Blvd Queens NY 11424
Staten Island Borough Hall 10 Richmond Terrace, Staten Island, NY 10301 10 Richmond Ter Staten Island NY 10301


\(\color{skyblue}{\textrm{- Geolocating}}\)

library(tidygeocoder)

processed <- boro_halls_parsed %>% 
  geocode(address = pm.address, method = "osm", verbose = TRUE, unique_only = TRUE)

boro_halls <- boro_halls_parsed %>% 
  full_join(processed, by = c("pm.address" = "address" )) %>% 
  st_as_sf(coords = c("long", "lat"), crs = 4326)

boro_halls
hall street pm.address geometry
New York City Hall New York City Hall, New York, NY 10007 New York City Hall New York NY 10007 POINT (-74.00595 40.71274)
Manhattan Municipal Building 31 Chambers St, New York, NY 10007 31 Chambers St New York NY 10007 POINT (-74.00448 40.71357)
Bronx County Courthouse 851 Grand Concourse, Bronx, NY 10451 851 Grand Concourse Bronx NY 10451 POINT (-73.92332 40.82611)
Brooklyn Borough Hall 209 Joralemon St, Brooklyn, NY 11201 209 Joralemon St Brooklyn NY 11201 POINT (-73.99054 40.69263)
Queens Borough Hall 120-55 Queens Blvd, Queens, NY 11424 120-55 Queens Blvd Queens NY 11424 POINT (-73.8283 40.71378)
Staten Island Borough Hall 10 Richmond Terrace, Staten Island, NY 10301 10 Richmond Ter Staten Island NY 10301 POINT (-74.07609 40.64242)

\(\color{dodgerblue}{\textbf{Projection}}\)


\(\color{skyblue}{\textrm{- Checking}}\)

boro_halls

boro_halls %>% st_crs()
Coordinate Reference System:
  User input: EPSG:4326 
  wkt:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    USAGE[
        SCOPE["Horizontal component of 3D system."],
        AREA["World."],
        BBOX[-90,-180,90,180]],
    ID["EPSG",4326]]


\(\color{skyblue}{\textrm{- Reprojecting}}\)

Name Code
World Geodetic System 1984 (WGS 84) 4326
NAD83 / New York Long Island 2263
boro_halls <- boro_halls %>% 
  st_transform(2263)

\(\color{dodgerblue}{\textbf{Plotting}}\)

#First getting shapefiles from the census tigris packages (see section on census data)
library(tigris)
options(tigris_class = "sf")

ny_counties <- counties(state = "NY", cb = TRUE, progress_bar = FALSE) %>% 
  as_tibble() %>% 
  filter(NAME %in% c("Bronx", "New York", "Kings", "Queens", "Richmond")) %>% 
  st_as_sf() %>% 
  st_transform(crs = 2263) %>% 
  bind_cols(population = c(2405464, 2736074, 1694251, 1472654, 495747))


\(\color{skyblue}{\textrm{- Basic}}\)

ggplot() + 
  geom_sf(data = ny_counties, aes(fill = population)) + 
  geom_sf(data = boro_halls, color = "red", size = 2) + 
  theme(axis.text.x = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks = element_blank(),
        rect = element_blank()) + 
  scale_fill_viridis_c()


\(\color{skyblue}{\textrm{- Basemap}}\)

library(ggspatial)

Options:

Bounding box to zoom:

boro_halls %>% 
  st_transform(4326) %>% 
  ggplot() + 
  annotation_map_tile(type = "cartolight", zoomin = 0) +
  geom_sf(color = "red", size = 1.5) + 
  coord_sf(xlim = c(-74.2591, -73.7002), 
           ylim = c(40.4774, 40.9162), 
           expand = FALSE) +
  theme(axis.text.x = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks = element_blank(),
        rect = element_blank())

\(\color{darkblue}{\textbf{Leaflet}}\)


Used for processing spatial data and basic visualization

library(leaflet)
library(leafpop)
library(leaflet.mapboxgl) # remotes::install_github("rstudio/leaflet.mapboxgl")

\(\color{dodgerblue}{\textbf{Basic Map}}\)

leaflet() %>% 
  addTiles() %>%
  addMarkers(lng = -74.000060, lat = 40.730910)

\(\color{dodgerblue}{\textbf{Zoom}}\)

Far (zoom = 10)

leaflet() %>% 
  addTiles() %>%
  setView(lng = -74.000060, lat = 40.730910, zoom = 10) %>% 
  addMarkers(lng = -74.000060, lat = 40.730910)


Close (zoom = 100)

leaflet() %>% 
  addTiles() %>%
  setView(lng = -74.000060, lat = 40.730910, zoom = 100) %>% 
  addMarkers(lng = -74.000060, lat = 40.730910)

\(\color{dodgerblue}{\textbf{Markers}}\)

boro_hall_points <- boro_halls %>% 
  st_transform(4326) %>% 
  st_coordinates() 

boro_halls <- boro_halls %>%  
  st_set_geometry(NULL) %>% 
  bind_cols(tibble(long = boro_hall_points[,1],
                   lat = boro_hall_points[,2]))


\(\color{skyblue}{\textrm{- Pin}}\)

boro_halls %>% 
  leaflet() %>% 
  addTiles() %>%
  addMarkers(lng = ~long, lat = ~lat)


\(\color{skyblue}{\textrm{- Colored Circle}}\)

boro_halls %>% 
  leaflet() %>% 
  addTiles() %>%
  addCircleMarkers(radius = 6,
                   color = "red",
                   fillOpacity = 0.8,
                   stroke = FALSE)

\(\color{dodgerblue}{\textbf{Labels}}\)

ny <- paste(sep = "<br/>",
            "<b><a href='https://www1.nyc.gov/'>City Hall</a></b>",
                 "City Hall Park",
                 "New York, NY 10007")

bx <- paste(sep = "<br/>",
            "<b><a href='https://bronxboropres.nyc.gov/'>Bronx Borough Hall</a></b>",
                 "851 Grand Concourse",
                 "Bronx, NY 10451")

bk <- paste(sep = "<br/>",
            "<b><a href='https://www.brooklyn-usa.org/'>Brooklyn Borough Hall</a></b>",
                 "209 Joralemon St",
                 "Brooklyn, NY 11201")

mn <- paste(sep = "<br/>",
            "<b><a href='https://www.manhattanbp.nyc.gov/'>Manhattan Borough Hall</a></b>",
                 "31 Chambers St",
                 "New York, NY 10007")

qn <- paste(sep = "<br/>",
            "<b><a href='https://queensbp.org/'>Queens Borough Hall</a></b>",
                 "120-55 Queens Blvd",
                 "Queens, NY 11424")

si <- paste(sep = "<br/>",
            "<b><a href='https://www.statenislandusa.com/'>Staten Island Borough Hall</a></b>",
                 "10 Richmond Terrace",
                 "Staten Island, NY 10301")

boro_halls <- boro_halls %>% 
  mutate(label = c(ny, mn, bx, bk, qn, si))


\(\color{skyblue}{\textrm{- Popups}}\)

boro_halls %>% 
  leaflet() %>% 
  addTiles() %>%
  addMarkers(lng = ~long, lat = ~lat,
             popup = ~label)


\(\color{skyblue}{\textrm{- Hover}}\)

labels <- sprintf(str_glue("{boro_halls$hall}<br>{boro_halls$street}")) %>% 
  lapply(htmltools::HTML)

boro_halls %>% 
  leaflet() %>% 
  addTiles() %>%
  addMarkers(lng = ~long, lat = ~lat,
             label = labels)


\(\color{skyblue}{\textrm{- Formatting}}\)

leaflet() %>% 
  addTiles() %>% 
  setView(-118.456554, 34.09, 13) %>%
  addMarkers(lng = -118.456554, lat = 34.105,
             label = "Default Label",
             labelOptions = labelOptions(noHide = T)) %>%
  addMarkers(lng = -118.456554, lat = 34.095,
             label = "Label w/o surrounding box",
             labelOptions = labelOptions(noHide = T, 
                                         textOnly = TRUE)) %>%
  addMarkers(lng = -118.456554, lat = 34.085,
             label = "label w/ textsize 15px",
             labelOptions = labelOptions(noHide = T, 
                                         textsize = "15px")) %>%
  addMarkers(lng = -118.456554, lat = 34.075,
             label = "Label w/ custom CSS style",
             labelOptions = labelOptions(noHide = T, 
                                         direction = "bottom",
                                         style = list("color" = "red",
                                                      "font-family" = "serif",
                                                      "font-style" = "italic",
                                                      "box-shadow" = "3px 3px rgba(0,0,0,0.25)",
                                                      "font-size" = "12px",
                                                      "border-color" = "rgba(0,0,0,0.5)")))

\(\color{dodgerblue}{\textbf{Polygons}}\)

#First getting data from the census to plot (see section on census data)
library(tidycensus)
population <- get_acs(geography = "county",
                      state = "NY",
                      variables = c(population = "B01003_001"),
                      year = 2019, 
                      survey = "acs5",
                      geometry = TRUE) %>% 
  mutate(pretty_estimate = scales::comma(estimate),
         legend_value = estimate / 10000) %>% 
  st_as_sf()
pal <- colorBin("viridis", domain = population$legend_value)

labels <- sprintf("<strong>%s</strong><br/>Population: %s",
                  population$NAME, population$pretty_estimate) %>% 
  lapply(htmltools::HTML)

population %>% 
  leaflet() %>% 
  addTiles() %>% 
  addPolygons(fillColor = ~pal(legend_value),
              fillOpacity = 0.7,
              color = "white",
              weight = 1,
              opacity = 1,
              smoothFactor = 0.5,
              highlight = highlightOptions(weight = 5,
                                           color = "white",
                                           fillOpacity = 0.7,
                                           bringToFront = TRUE),
              label = labels,
              labelOptions = labelOptions(style = list("font-weight" = "normal", 
                                                       padding = "3px 8px"),
                                          textsize = "15px",
                                          direction = "auto")) %>% 
  addLegend(pal = pal, 
            values = ~legend_value, 
            opacity = 0.7, 
            title = "Population (10K)",
            position = "bottomright")

Return to Main Page